import { AppState } from "@/interface";
import { MicroActionService } from "./micro-action-service";
import { Interceptors } from "@/net";
import apps from '@/micro/apps';
import { startQiankun, AppState as AppStateObj } from "@/micro";
import { clearCookie } from "@/utils/util";

/**
 * 应用服务
 *
 * @export
 * @class AppService
 */
export class AppService {

    /**
     * 唯一实例
     * 
     * @private
     * @static
     * @memberof AppService
     */
    private static readonly instance = new AppService();

    /**
     * 获取唯一实例
     *
     * @static
     * @return {*}  {AppService}
     * @memberof AppService
     */
    public static getInstance(): AppService {
        return AppService.instance;
    }

    /**
     * 消息对象实例
     * 
     * @private
     * @memberof AppService
     */
    private static AppState: any

    /**
     * 消息状态事件
     *
     * @protected
     * @type {*}
     * @memberof AppService
     */
    private static AppStateEvent: any;

    /**
     * 当前挂载微应用
     *
     * @private
     * @memberof AppService
     */
    private static MountedMicroApp: any;

    /**
     * 消息队列
     *
     * @private
     * @static
     * @type {AppState[]}
     * @memberof AppService
     */
    private static msgQueue: AppState[] = [];

    /**
     * 应用数据
     *
     * @private
     * @type {*}
     * @memberof AppService
     */
    private static appData: any;

    /**
     * 获取消息对象
     *
     * @static
     * @return {*}  {*}
     * @memberof AppService
     */
    public getAppState() {
        return AppService.AppState;
    }

    /**
     * 设置消息对象实例
     *
     * @param {*} AppState
     * @memberof AppService
     */
    public setAppState(AppState: any) {
        AppService.AppState = AppState;
    }

    /**
     * 获取应用数据
     *
     * @memberof AppService
     */
    public getAppData() {
        return AppService.appData;
    }

    /**
     * 设置应用数据
     *
     * @param {*} args
     * @memberof AppService
     */
    public setAppData(args: any) {
        AppService.appData = args;
    }

    /**
     * 获取已挂载微应用
     *
     * @static
     * @return {string}  {*}
     * @memberof AppService
     */
    public getMountedMicroApp() {
        return AppService.MountedMicroApp;
    }

    /**
     * 添加已挂载微应用
     *
     * @param {*} app
     * @memberof AppService
     */
    public addMountedMicroApp(app: any) {
        AppService.MountedMicroApp = app;
    }

    /**
     * 删除已挂载微应用
     *
     * @param {*} app
     * @memberof AppService
     */
    public removeMountedMicroApp(app: any) {
        AppService.MountedMicroApp = undefined;
    }

    /**
     * 初始化应用
     *
     * @static
     * @memberof AppService
     */
    public initApp(router: any) {
        Interceptors.init(router);
        this.setAppState(AppStateObj);
        AppService.AppStateEvent = this.getAppState().subscribe((state: AppState) => {
            const { tag } = state;
            if (Object.is(tag, 'BASEAPP')) {
                this.handleMicroApp(state);
            }
        })
        startQiankun({
            prefetch:'all',
            getTemplate: (tpl: string) => {
                const reg = /<div id="app-loading-x"[\S\s]*<\/div>/g;
                if (tpl.search(reg) !== -1) {
                    return tpl.replace(reg, `<div id="app-loading-x" class="el-loading-mask app-loading">
                    <div class="app-loading-icon">
                        <div class="icon-content">
                            <div class="app-loading-icon-item active-color"></div>
                            <div class="app-loading-icon-item"></div>
                        </div>
                        <div class="icon-content">
                            <div class="app-loading-icon-item"></div>
                            <div class="app-loading-icon-item"></div>
                        </div>
                    </div>
                </div>`);
                }
                return tpl;
            }
        });
    }

    /**
     * 销毁应用
     *
     * @static
     * @memberof AppService
     */
    public destroyApp() {
        if (AppService.AppStateEvent) {
            AppService.AppStateEvent.unsubscribe();
        }
    }

    /**
     * 通知单个微应用
     *
     * @param {AppState} state
     * @memberof AppService
     */
    public noticeMicroApp(state: AppState) {
        if (this.getMountedMicroApp() && Object.is(this.getMountedMicroApp().name, state.tag)) {
            this.getAppState().next(state);
        } else {
            AppService.msgQueue.push(state);
        }
    }

    /**
     * 通知全部微应用
     *
     * @memberof AppService
     */
    public noticeAllMicroApp(action: string, data?: any) {
        if (apps && apps.length > 0) {
            apps.forEach((app: any) => {
                if (this.getMountedMicroApp() && Object.is(this.getMountedMicroApp().name, app.name)) {
                    this.getAppState().next({ tag: app.name, action, data });
                } else {
                    AppService.msgQueue.push({ tag: app.name, action, data });
                }
            })
        }
    }

    /**
     * 处理微应用抛出事件
     *
     * @param {AppState} state
     * @memberof AppService
     */
    public handleMicroApp(state: AppState) {
        const { action, data } = state;
        if (Object.is(action, 'MICROAPPINITED')) {
            if (AppService.msgQueue.length > 0) {
                AppService.msgQueue.forEach((queue: any, index: number) => {
                    if (Object.is(queue.tag, data.tag)) {
                        this.noticeMicroApp(queue);
                        AppService.msgQueue.splice(index, 1);
                    }
                })
            }
        } else {
            MicroActionService.getInstance().handleAction(state);
        }
    }

    /**
     * 清除应用数据
     *
     * @private
     * @memberof AppService
     */
    public clearAppData() {
        clearCookie("ibzuaa-token", true);
        clearCookie("ibzuaa-expired", true);
        clearCookie("ibzuaa-user", true);
        clearCookie('dcsystem', true);
        clearCookie('activeOrgData', true);
        clearCookie('orgsData', true);
        clearCookie('loginname', true);
    }
}